package main;

import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.MultipartConfigElement;
import javax.servlet.Servlet;
import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.lang3.StringUtils;
import org.rythmengine.spring.web.RythmHolder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration;
import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.DispatcherServlet;

import com.mgfireworks.mgplatform.TomcatEmbeddedFactory;
import com.mgfireworks.mgplatform.WebAppConfig;

import cn.hn.java.summer.BaseApp;
import cn.hn.java.summer.db.SnJdbcTemplate;
import cn.hn.java.summer.db.multiple.MultipleDataSource;
import cn.hn.java.summer.db.paging.MysqlPagingConverter;
import cn.hn.java.summer.mvc.RythmViewHolder;
import cn.hn.java.summer.utils.AppUtils;

@EnableAutoConfiguration(exclude = {ErrorMvcAutoConfiguration.class})
@SpringBootApplication(scanBasePackages={"com.mgfireworks.mgplatform","cn.hn.java.summer.cache"})
@Configuration()
@EnableTransactionManagement
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class App extends BaseApp
{
    public static void main( String[] args ) throws URISyntaxException, IOException
    {
    	SpringApplication.run(App.class);
    }

    @Bean
    @ConfigurationProperties(prefix = "datasource")
    public DataSource dataSource() {
        return new BasicDataSource();
    }
 
    @Bean
    public PlatformTransactionManager txManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    @Bean
    public MultipleDataSource multipleDataSource(){
    	MultipleDataSource dataSource=new MultipleDataSource();
    	List<SnJdbcTemplate> templates=new ArrayList<SnJdbcTemplate>();
    	SnJdbcTemplate template=new SnJdbcTemplate();
    	template.setDataSource(dataSource());
    	template.setPagingConverter(new MysqlPagingConverter());
    	templates.add(template);
    	dataSource.setJdbcTemplates(templates);
    	return dataSource;
    }
    
    @Bean
    public ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet) {
    	ServletRegistrationBean registration = new ServletRegistrationBean(
                dispatcherServlet);
        dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
        return registration;
    }
    
    /**
     * 文件上传配置
     * @param maxFileSize
     * @param maxRequestSize
     * @return
     */
    @Bean  
    public MultipartConfigElement multipartConfigElement(
    		@Value("${fileupload.maxFileSize}")
    		final String maxFileSize,
    		@Value("${fileupload.maxFileSize}")
    		final String maxRequestSize
    	) {  
        MultipartConfigFactory factory = new MultipartConfigFactory();  
        factory.setMaxFileSize(maxFileSize);  
        factory.setMaxRequestSize(maxRequestSize); 
        return factory.createMultipartConfig();  
    }  
    
    
    @Bean
    public RythmHolder rythmHolder(
		@Value("${template.home}") final String templateHome,
		@Value("${template.mode}") final String mode
    ){
    	configWebRoot(templateHome);
    	return new RythmViewHolder(WebAppConfig.webRootDir, mode);
    }

    
    /**
     * 覆盖spring boot内置tomcat的docbase设置
     * @author songjiangang
     * @time 2016年5月10日 上午11:13:42
     */

	@ConditionalOnClass({ Servlet.class, Tomcat.class })
	public static class EmbeddedTomcat {

		@Bean
		public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory(
				@Value("${server.tomcat.docbase}") final String docBase
		) {
			configWebRoot(docBase);
			return new TomcatEmbeddedFactory();
		}

	}

	/**
	 * 配置网站根目录
	 * @param templateHome
	 */
	private static void configWebRoot(String templateHome){
		if(WebAppConfig.webRootDir!=null){
			return;
		}
		
		String templateHome1=templateHome;
		//配置模板文件存放根目录
		String templateDir=templateHome;
		//如果未指定目录则取程序根目录
		if(StringUtils.isBlank(templateHome)){
			templateHome1="./";
		}
		//在项目当前目录
		if(templateHome1.startsWith("./")){
			String appRoot=AppUtils.getAppRoot();
			templateDir=Paths.get(appRoot, templateHome1.substring(1)).toString();
		}
		
		//设置网站根目录
    	WebAppConfig.webRootDir=templateDir;
	}
}